package edu.gyc.appshiro.controller;


import edu.gyc.appshiro.model.User;
import edu.gyc.appshiro.service.UserService;
import edu.gyc.appshiro.shiro.MakePassword;
import edu.gyc.appshiro.shiro.ShiroRealm;
import edu.gyc.appshiro.vo.UserRoleVo;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ls
 * @since 2021-02-02
 */
@Controller
@Slf4j
public class UserController {
    @GetMapping("/login")
    public String login() {


        return "/";
    }

    @PostMapping("/login")
    public String dologin(User user, HttpServletRequest request) {

        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(usernamePasswordToken);
            User userInfo = (User) subject.getPrincipal();
            userInfo.setPassword("");
            subject.getSession().setAttribute("user", user);

        } catch (Exception e) {
            //登录失败从request中获取shiro处理的异常信息 shiroLoginFailure:就是shiro异常类的全类名
//            String exception = (String) request.getAttribute("shiroLoginFailure");
            String msg = "";
            if (e instanceof UnknownAccountException) {
                msg = "用户名错误了！";
            } else if (e instanceof IncorrectCredentialsException) {
                msg = "密码错误了！";
            } else {
                msg = e.getMessage();
            }

            request.setAttribute("msg", msg);
            return "login2";
        }
        return "menu";
    }

    /**
     * 登出  这个方法没用到,用的是shiro默认的logout
     * 在ShiroConfig//logout是shiro提供的过滤器
     * filterChainDefinitionMap.put("/logout", "logout");
     * 若要使用可以注释上面这个方法，就可调用下面方法注销用户
     */

    @Autowired
    ShiroRealm shiroRealm;

    @RequestMapping("/logout")
    public String logout() {

        Subject subject = SecurityUtils.getSubject();
        User user=(User)subject.getPrincipal();
        log.info( user.getUsername() + "退出系统.");
        subject.logout();

        //shiro登出时，没有销毁缓存，下一次登录直接从缓存获取密码，修改密码后应销毁缓存
        //自定义清除缓存
        Cache<Object, AuthenticationInfo> cache=shiroRealm.getAuthenticationCache();
        if (cache!=null){
            cache.remove(user.getUsername());
        }


        return "/";
    }

    @GetMapping("/unauthorized")
    public String unauthorized() {
        return "unauthorized";
    }

    @Autowired
    UserService userService;

    @GetMapping("/reg")
    public String reg() {
        return "/reg";
    }

    @PostMapping("/reg")
    public String doreg(String username, String password, Model model) {
        boolean isSuccess = false;
        String msg = "";

        if (username.isBlank() || password.isBlank()) {
            model.addAttribute("isSuccess", isSuccess);
            return "/reg";
        }
        User user = userService.lambdaQuery().eq(User::getUsername, username).one();
        if (user != null) {
            msg = "用户名已被使用，换一个吧！";
            model.addAttribute("msg", msg);
            model.addAttribute("isSuccess", isSuccess);
            return "/reg";
        }

        String salt = RandomStringUtils.randomAlphabetic(6);
        String newpass = MakePassword.make(password, salt);

        User newUser = new User();
        newUser.setUsername(username);
        newUser.setPassword(newpass);
        newUser.setSalt(salt);
        userService.save(newUser);
        msg = "恭喜你注册成功！";
        model.addAttribute("msg", msg);
        isSuccess = true;
        model.addAttribute("isSuccess", isSuccess);
        return "/reg";

    }

    @RequestMapping("/user/roleuser")
    public String userRole(Model model) {
        Set<UserRoleVo> userRoleVoSet = userService.getUserRoles();
        model.addAttribute("userroles", userRoleVoSet);
        return "/admin/userrole";
    }

    @GetMapping("/user/newpass")
    public String newpass(Model model) {

        return "/admin/newpass";
    }

    @PostMapping("/user/newpass")
    public String editnewpass(String oldpass, String password, Model model) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        boolean r = userService.newPassword(user.getUid(), oldpass, user.getSalt(), password);
        String msg = "";
        if (r) {
            msg = "密码修改成功！";

        } else {
            msg = "旧密码输入错误！";
        }
        model.addAttribute("msg", msg);
        return "/admin/newpass";
    }
}

